﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.Data.Entity.Spatial;
using System.Data.Entity.Core.Objects;

namespace TreeManagement
{
    public partial class ViewPanel : UserControl
    {
        public ViewPanel()
        {
            InitializeComponent();
        }
        public List<Tree> Trees;
        public List<Ward> Wards;
        public List<Road> Roads;
        
        public List<Point> DistrictPoints;
  
        public List<Point> RecordedPoints = new List<Point>();
        private List<IRecordPoint>recordPoints = new List<IRecordPoint>();
        public Tuple<Point, int> RRect;
        private void ViewPanel_Paint(object sender, PaintEventArgs e)
        {
            Graphics myGraphics = e.Graphics;
            Matrix myMatrix = new Matrix(1, 0, 0, -1, 0, 0);
            //myGraphics.Transform = myMatrix;
            //myGraphics.TranslateTransform(0,300, MatrixOrder.Append);
            // draw coordinate system
           

            if (DistrictPoints != null)
            {
                drawDistrict(myGraphics,DistrictPoints.ToArray());
            }
            drawWards(myGraphics);
            drawRoads(myGraphics);
            drawTrees(myGraphics);
            foreach (IRecordPoint r in recordPoints)
                r.drawRecordedPoint(myGraphics);

            if (RRect != null)
                TMUtils.fillEclipse(myGraphics, RRect.Item1, RRect.Item2);

            drawCoordinateSystem(myGraphics);   

            // Create the path.
            //GraphicsPath myGraphicsPath = new GraphicsPath();
            //Rectangle myRectangle = new Rectangle(0, 0, 60, 60);
            //myGraphicsPath.AddRectangle(myRectangle);

            //SolidBrush solidBrush1 = new SolidBrush(Color.Blue);
            // Fill the path on the new coordinate system. 
            // No local transformation
           // myGraphics.FillPath(solidBrush1, myGraphicsPath);
        }
        private void drawCoordinateSystem(Graphics g)
        {
            Brush brush = new SolidBrush(Color.Black);
            Pen pen = new Pen(brush,1);
            g.DrawLine(pen, new Point(0, 0), new Point(0, this.Height));
            g.DrawLine(pen, new Point(0, 0), new Point(this.Width, 0));

            System.Drawing.Font font = new System.Drawing.Font("Arial", 10);
            //draw X:
            int x = 0;
            while (x < this.Width)
            {
                g.DrawRectangle(pen, new Rectangle(x, 0, 2, 2));
                g.DrawString(x+"", font, brush, new Point(x, 0));
	    	    x+=TMConsts.COORDINATE_DELIMER;
            }
            int y = 0;
            while (y < this.Height)
            {
                g.DrawRectangle(pen, new Rectangle(0, y, 2, 2));
                g.DrawString(y + "", font, brush, new Point(0, y));
                y += TMConsts.COORDINATE_DELIMER;
            }
            
        }
        
        private void drawDistrict(Graphics g, Point[]points)
        {                 
            SolidBrush solidBrush1 = new SolidBrush(Color.Gray);           
            if (points.Length > 0)
                g.FillPolygon(solidBrush1, points);
        }
        
     
       
        
        private void ViewPanel_Load(object sender, EventArgs e)
        {
            
        }

        public void registerRecodePoint(IRecordPoint recordPoint){
            recordPoints.Add(recordPoint);
        }
        public void unregisterRecordedPoint(IRecordPoint recordedPoint)
        {
            recordPoints.Remove(recordedPoint);
        }
        private void notifyRecordPoint(Point p)
        {
            foreach (IRecordPoint r in recordPoints)
                r.notifyRecordPoint(p);
        }
       
        private void ViewPanel_MouseDown(object sender, MouseEventArgs e)
        {
            notifyRecordPoint(e.Location);
        }
        private void drawWards(Graphics g)
        {
            if (Wards == null || Wards.Count <= 0)
                return;
            using (var dbContext = new TreeDBEntities())
            {
                int index = 0;
                foreach (Ward ward in Wards)
                {
                    int count = (int)ward.Polygon.PointCount;
                    if (count > 0)
                    {
                        List<Point> points = new List<Point>();
                        for (int i = 1; i <= count; i++)
                        {
                            DbGeometry geo = ward.Polygon.PointAt(i);
                            points.Add(new Point((int)geo.XCoordinate, (int)geo.YCoordinate));
                        }
                        g.FillPolygon(TMUtils.getRandomPolygonBrush(index), points.ToArray());
                        //draw text
                        DbGeometry center = ward.Polygon.Centroid;
                        TMUtils.drawString(g, ward.Name, TMUtils.getRandomTextBrush(index), new Point((int)center.XCoordinate, (int)center.YCoordinate));
                        index++;
                    }
                }
            }
        }
        private void drawRoads(Graphics g)
        {
            if (Roads == null || Roads.Count <= 0)
                return;
            using (var dbContext = new TreeDBEntities())
            {
                int index = 0;
                foreach (Road ward in Roads)
                {
                    int count = (int)ward.Line.PointCount;                   
                    if (count > 0)
                    {
                        List<Point> points = new List<Point>();
                        for (int i = 1; i <= count; i++)
                        {
                            DbGeometry geo = ward.Line.PointAt(i);
                            points.Add(new Point((int)geo.XCoordinate, (int)geo.YCoordinate));
                        }
                        if (points.Count > 0)
                        {
                            Brush brush = new SolidBrush(TMUtils.getRandomLineColor(index));
                            Pen p = new Pen(brush, TMConsts.LINE_WIDTH);
                            for (int i = 0; i < points.Count - 1; i++)
                            {
                                g.DrawLine(p, points[i], points[i + 1]);
                            }
                            
                            TMUtils.drawString(g, ward.Name, brush, points[0]);
                            index++;
                        }
                    }
                }
            }
        }
        private void drawTrees(Graphics g)
        {
            if (Trees == null || Trees.Count <= 0)
                return;
            using (var dbContext = new TreeDBEntities())
            {
                foreach (Tree tree in Trees)
                {
                    DbGeometry geo = tree.Point;
                    Point p = new Point((int)geo.XCoordinate, (int)geo.YCoordinate);
                    g.DrawImage(Properties.Resources.tree_icon, new Rectangle(p.X - TMConsts.TREE_SIZE / 2, p.Y - TMConsts.TREE_SIZE / 2, TMConsts.TREE_SIZE, TMConsts.TREE_SIZE));
                }
            }
        }

        
    }
}
